<template>
  <div class="container my-5">
    <!-- 1. 视图切换和标题 -->
    <div class="d-flex justify-content-between align-items-center mb-4 pb-2 border-bottom">
      <h3 class="view-switcher">
        <span @click="currentView = 'list'" :class="{ 'active': currentView === 'list' }">
          我的事务
        </span>
        <span class="mx-2 text-muted">|</span>
        <span @click="currentView = 'calendar'" :class="{ 'active': currentView !== 'list' }">
          日历视图
        </span>
      </h3>
    </div>

    <!-- ======================================================= -->
    <!-- 2. 列表视图                                             -->
    <!-- ======================================================= -->
    <div v-if="currentView === 'list'">
      <!-- 紧急事务区域 -->
      <div class="task-section mb-5">
        <h4 class="task-section-title">
          紧急事务
          <span v-if="unhandledUrgentTasksCount > 0" class="badge bg-danger rounded-pill ms-2">
            {{ unhandledUrgentTasksCount }}
          </span>
        </h4>
        <div class="task-list">
          <div v-for="task in urgentTasks" :key="task.id" class="task-card" :class="getUrgentClass(task.urgency)"
          @click="openTaskDetail(task.id)" style="cursor: pointer;">
            <div class="task-card-main">
              <div class="task-card-title">
                {{ task.title }}
                <span v-if="task.status === '待办' || task.status === '未读'" class="badge bg-danger ms-2">{{ task.status }}</span>
              </div>
              <div class="task-card-publisher">
                发布者ID: {{ task.publisher }}
              </div>
            </div>
            <div class="task-card-meta">
              <div class="task-card-dates">
                <span>{{ task.startDate }}</span><span class="mx-1 text-muted">至</span><span>{{ task.endDate }}</span>
              </div>
              <button v-if="task.status === '未读' || task.status === '待办'" class="btn btn-sm btn-outline-primary" @click.stop="handleTaskAction(task)">
                {{ task.status === '未读' ? '设为待办' : '设为已办' }}
              </button>
            </div>
          </div>
        </div>
      </div>

      <!-- 分组事务区域 -->
      <!-- 加载状态 -->
      <div v-if="isLoading" class="text-center p-5">
        <div class="spinner-border" role="status">
          <span class="visually-hidden">Loading...</span>
        </div>
        <p class="mt-2">正在加载事务数据...</p>
      </div>
      <!-- 空状态 -->
      <div v-else-if="taskGroups.length === 0" class="text-center p-5 text-muted">
        <p>暂无常规事务</p>
      </div>
      <!-- 数据渲染 (已修复：将 v-for 移入 v-else) -->
      <div v-else>
        <div v-for="group in taskGroups" :key="group.id" class="task-section mb-4">
          <!-- 可点击的标题区域 -->
          <div class="task-section-header" @click="toggleSection(group.id)" :class="{ 'is-collapsed': isSectionCollapsed(group.id) }">
            <h4 class="task-section-title mb-0">{{ group.title }}</h4>
              <div class="ms-auto me-3 d-flex align-items-center" style="gap: 0.5rem;">
                <!-- 1. 待办角标 (黑色) -->
                <span v-if="getTodoCount(group) > 0" class="badge bg-primary rounded-pill">
                  待办 ({{ getTodoCount(group) }})
                </span>
                <!-- 2. 未读角标 (红色) -->
                <span v-if="getUnreadCount(group) > 0" class="badge bg-danger rounded-pill">
                  未读 ({{ getUnreadCount(group) }})
                </span>
              </div>
            <svg class="chevron-icon" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
              <path fill-rule="evenodd" d="M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z"/>
            </svg>
          </div>

          <!-- 带动画效果的任务列表 -->
          <transition name="slide-fade">
            <div v-show="!isSectionCollapsed(group.id)" class="task-section-body mt-3">
              <div class="task-list">
                <div v-for="task in getVisibleTasks(group)" :key="task.id" class="task-card" @click="openTaskDetail(task.id)" style="cursor: pointer;">
                   <div class="task-card-main">
                      <div class="task-card-title">
                        {{ task.title }}
                        <span v-if="task.status === '未读'" class="badge bg-danger ms-2">未读</span>
                      </div>
                      <div class="task-card-publisher">
                        {{ parsePublisherInfo(task) }}
                      </div>
                    </div>
                    <div class="task-card-meta">
                      <div class="task-card-dates">
                        <span>{{ task.startDate.split(' ')[0] }}</span><span class="mx-1 text-muted">至</span><span>{{ task.endDate.split(' ')[0] }}</span>
                      </div>
                      <button v-if="task.status === '未读' || task.status === '待办'" class="btn btn-sm btn-outline-primary" @click.stop="handleTaskAction(task)">
                {{ task.status === '未读' ? '设为待办' : '设为已办' }}
              </button>
                    </div>
                </div>
                <div v-if="group.tasks.length > 3" class="text-center mt-3">
                  <button class="btn btn-link" @click="toggleGroupExpansion(group.id)">
                    {{ isGroupExpanded(group.id) ? '收起' : `查看全部 ${group.tasks.length} 条...` }}
                  </button>
                </div>
              </div>
            </div>
          </transition>
        </div>
      </div>
    </div>

    <!-- ======================================================= -->
    <!-- 3. 日历视图                                             -->
    <!-- ======================================================= -->
    <div v-if="currentView === 'calendar'">
      <!-- ... 日历视图的模板代码保持不变 ... -->
       <div class="calendar-controls text-center mb-3">
        <button class="btn btn-outline-primary btn-sm me-2" @click="previousMonth"> < 上一月  </button>
        <span class="calendar-title h5">{{ currentMonthDisplay }}</span>
        <button class="btn btn-outline-primary btn-sm ms-2" @click="nextMonth">下一月 > </button>
      </div>
      <div class="calendar-grid">
        <div class="calendar-header">
          <div v-for="dayName in dayNames" :key="dayName" class="calendar-cell header-cell">{{ dayName }}</div>
        </div>
        <div v-for="(week, weekIndex) in calendarWeeks" :key="weekIndex" class="calendar-week">
          <div
            v-for="day in week"
            :key="day.fullDate"
            class="calendar-cell day-cell"
            :class="{
              'other-month': !day.isCurrentMonth,
              'today': day.isToday,
              'has-tasks': day.tasks.length > 0,
              'selected': selectedDate && day.fullDate === selectedDate.toISOString().split('T')[0],
               'is-deadline': day.isDeadlineDay
            }"
            @click="selectDate(day)"
          >
             <div class="day-number-container">
              <span v-if="day.isDeadlineDay && day.isCurrentMonth" class="deadline-badge">截</span>
              <div class="day-number">{{ day.day }}</div>
            </div>
            <div class="task-indicators">
              <template v-for="task in day.tasks.slice(0, 3)" :key="task.id">
                <span
                  class="task-dot"
                  :class="getUrgentClassForDot(task.urgency || 'default')"
                  :title="task.title"
                ></span>
              </template>
              <span v-if="day.tasks.length > 3" class="task-dot more-tasks-dot" :title="`还有 ${day.tasks.length - 3} 个事务`">...</span>
            </div>
          </div>
        </div>
      </div>
      <div v-if="selectedDateTasks.length > 0" class="mt-4 selected-day-tasks">
        <h5>{{ selectedDateFormatted }} 的事务:</h5>
        <ul class="list-group list-group-flush">
          <li v-for="task in selectedDateTasks" :key="task.id" class="list-group-item bg-transparent d-flex justify-content-between align-items-center">
            <div>
              <strong>{{ task.title }}
                <span v-if="task.isEndingToday" class="badge bg-danger ms-2">今日截止</span>
              </strong>
              <br>
              <br>
            </div>
            <span class="badge" :class="getUrgentBadgeClass(task.urgency || 'low')">{{ task.urgency ? '紧急度: ' + task.urgency : '常规' }}</span>
          </li>
        </ul>
      </div>
    </div>

    <!-- ======================================================= -->
    <!-- 4. 详情弹窗 (样式已更新)                                  -->
    <!-- ======================================================= -->
    <div v-if="selectedTask" class="modal-overlay" @click="closeModal">
      <div class="modal-container" @click.stop>
        <div class="modal-content">
          <h3 class="modal-title">事务详情</h3>
          <!-- 弹窗内容 (HTML结构无需改变) -->
          <div class="modal-body">
            <div class="detail-item">
              <label class="detail-label">事务名称</label>
              <p class="detail-value">{{ selectedTask.title }}</p>
            </div>
            <div class="detail-item">
              <label class="detail-label">发布者</label>
              <p class="detail-value">{{ selectedTask.senderName }}</p>
            </div>
             <div class="detail-item">
              <label class="detail-label">发布部门</label>
              <p class="detail-value">{{ selectedTask.senderDepartment || '无' }}</p>
            </div>
            <div class="detail-item">
              <label class="detail-label">状态</label>
              <span :class="['status-badge', selectedTaskStatusClass]">
                {{ selectedTask.status }}
              </span>
            </div>
            <div class="detail-item">
              <label class="detail-label">模板类型</label>
              <p class="detail-value">{{ selectedTask.templateType || '无' }}</p>
            </div>
            <div class="detail-item">
              <label class="detail-label">模板内容</label>
              <p class="detail-value">{{ selectedTask.templateContent || '无' }}</p>
            </div>
            <div class="detail-item">
              <label class="detail-label">附件</label>
              <!-- <p class="detail-value">{{ selectedTask.fileName || '无' }}</p> -->
               <button
               v-if="selectedTask.fileName"
               @click="previewFile(selectedTask.id)"
               class="modal-close-btn"
               >
                预览
               </button>
               <p class="detail-value">{{ selectedTask.fileName || '无'}}</p>
            </div>
            <!-- <div class="detail-item">
              <label class="detail-label">Excel文件</label>
              <p class="detail-value">{{ selectedTask.excelName || '无' }}</p>
            </div> -->
            <div class="detail-item">
              <label class="detail-label">Excel文件</label>
              <button
              v-if="selectedTask.excelName"
              @click="previewExcelFile(selectedTask.id)"
              class="modal-close-btn"
              >
                预览
              </button>
              <p class="detail-value">{{ selectedTask.excelName || '无'}}</p>
            </div>
            <div class="detail-item">
              <label class="detail-label">开始时间</label>
              <p class="detail-value">{{ formatDetailDate(selectedTask.startTime) }}</p>
            </div>
            <div class="detail-item">
              <label class="detail-label">截止时间</label>
              <p class="detail-value">{{ formatDetailDate(selectedTask.endTime) }}</p>
            </div>
          </div>
          <!-- 弹窗底部 -->
          <div class="modal-footer">
            <button @click="closeModal" class="modal-close-btn">
              关闭
            </button>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
// ... 你的 <script setup> 部分保持不变 ...
import { ref, computed, onMounted, watch } from 'vue';
// import { fetchMessagesForUser } from '@/services/api.js';
// 【1. 引入新的API函数】
import { useMatterStore } from '@/stores/Matter/Matter.js';
import { fetchMessagesForUser,markTaskAsHandled,fetchExcelFile} from '@/services/api.js';
import { getDetail } from '@/api/Matter';

// =================================================================
// 1. 核心状态与依赖
// =================================================================
const currentView = ref('list');      // 当前视图: 'list' 或 'calendar'
const isLoading = ref(true);          // 数据加载状态
const userId = ref(10000002);         // 当前用户ID，应从认证状态中获取
const urgentTasks = ref([]);          // 紧急事务列表
const taskGroups = ref([]);           // 分组事务列表
const today = new Date();
today.setHours(0, 0, 0, 0);


// 组件挂载后，调用 action 去获取后端数据
onMounted(() => {
  // 从 localStorage 中获取存储的用户信息字符串
  const userInfoString = localStorage.getItem('userInfo');


  if (userInfoString) {
    // 将 JSON 字符串解析回 JavaScript 对象
    const userInfo = JSON.parse(userInfoString);

    // 将获取到的 userId 赋值给 ref 变量
    userId.value = userInfo.userId;


  } else {
    // 处理用户未登录的情况
    console.error("未在 localStorage 中找到用户信息，用户可能未登录。");
  }
  console.log(userId.value)
});

// =================================================================
// 2. 数据获取与处理
// =================================================================

/**
 * 将后端返回的 Message 对象转换为前端 Task 对象
 * @param {object} message - 后端返回的原始消息对象
 * @returns {object} - 前端使用的 Task 对象
 */
function convertMessageToTask(message) {
  // 安全的日期格式化函数
  const formatDate = (dateStringOrTimestamp) => {
    if (!dateStringOrTimestamp) return 'N/A';
    const date = new Date(dateStringOrTimestamp);
    return date.toLocaleDateString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit' }).replace(/\//g, '-');
  };

  const startDate = message.startTime || message.sendTime;
  const endDate = message.endTime || startDate;

  return {
    id: message.messageId,
    title: message.title,
    status: message.status,
    publisher: ` ${message.senderUserId}`,
    startDate: formatDate(startDate),
    endDate: formatDate(endDate),
    urgency: message.importance === '紧急' ? 'high' : (message.importance === '重要' ? 'medium' : 'low'),
    publisherInfo: `发布者ID: ${message.senderUserId} | 发布时间: ${formatDate(message.sendTime)}`,
    // 为日历视图保留原始 Date 对象，提高性能
    parsedStartDate: startDate ? new Date(startDate) : null,
    parsedEndDate: endDate ? new Date(endDate) : null
  };
}

/**
 * 异步加载所有用户事务数据
 */
async function loadTasks() {
  isLoading.value = true;
  try {
    // 并行请求所有数据
    const [urgentRes, teachingRes, researchRes, competitionRes, trainingRes] = await fetchMessagesForUser(userId.value);


    // ====================== VVV 复制下面这段调试代码 VVV ======================

console.log('--- 原始数据检查 ---');
console.log('紧急事务原始数据:', JSON.parse(JSON.stringify(urgentRes.data)));
console.log('教学事务原始数据:', JSON.parse(JSON.stringify(teachingRes.data)));
console.log('教科研事务原始数据:', JSON.parse(JSON.stringify(researchRes.data)));
console.log('学科竞赛原始数据:', JSON.parse(JSON.stringify(competitionRes.data)));
console.log('学习培训原始数据:', JSON.parse(JSON.stringify(trainingRes.data)));

const findBadData = (data, category) => {
  if (!Array.isArray(data)) {
    console.error(`[${category}] 返回的不是一个数组!`, data);
    return;
  }
  const badItem = data.find(item => item.messageId === 0 || item.messageId == null);
  if (badItem) {
    console.error(`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!`);
    console.error(`在【${category}】中找到了错误的源数据!`, badItem);
    console.error(`!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!`);
  }
};

findBadData(urgentRes.data, '紧急事务');
findBadData(teachingRes.data, '教学事务');
findBadData(researchRes.data, '教科研事务');
findBadData(competitionRes.data, '学科竞赛');
findBadData(trainingRes.data, '学习培训');

console.log('--- 原始数据检查结束 ---');

// ====================== ^^^ 复制上面这段调试代码 ^^^ ======================
    // 处理并赋值紧急事务
    urgentTasks.value = urgentRes.data.map(convertMessageToTask);

    // 处理并赋值分组事务
    taskGroups.value = [
      { id: 'g1', title: '教学事务', tasks: teachingRes.data.map(convertMessageToTask) },
      { id: 'g2', title: '教科研事务', tasks: researchRes.data.map(convertMessageToTask) },
      { id: 'g3', title: '学科竞赛', tasks: competitionRes.data.map(convertMessageToTask) },
      { id: 'g4', title: '学习培训', tasks: trainingRes.data.map(convertMessageToTask) }
    ];

    // 初始化所有分组为折叠状态
    taskGroups.value.forEach(group => {
      collapsedSections.value[group.id] = true;
    });

  } catch (error) {
    console.error("加载事务数据失败:", error);
    // 可在此处添加用户友好的错误提示，例如使用 Toast 通知
  } finally {
    isLoading.value = false;
  }
}

// =================================================================
// 3. 列表视图逻辑
// =================================================================
const collapsedSections = ref({});  // 存储折叠的分组ID
const expandedGroups = ref({});     // 存储展开 "查看更多" 的分组ID
const INITIAL_VISIBLE_COUNT = 3;    // 分组中默认显示的任务数量

const unhandledUrgentTasksCount = computed(() => {
  return urgentTasks.value.filter(task => task.status === '待办' || task.status === '未读').length;
});

function toggleSection(groupId) {
  collapsedSections.value[groupId] = !collapsedSections.value[groupId];
}

function isSectionCollapsed(groupId) {
  return !!collapsedSections.value[groupId];
}

function toggleGroupExpansion(groupId) {
  expandedGroups.value[groupId] = !expandedGroups.value[groupId];
}

function isGroupExpanded(groupId) {
  return !!expandedGroups.value[groupId];
}

function getVisibleTasks(group) {
  if (group.tasks.length <= INITIAL_VISIBLE_COUNT || isGroupExpanded(group.id)) {
    return group.tasks;
  }
  return group.tasks.slice(0, INITIAL_VISIBLE_COUNT);
}

//显示未读事务数量
function getUnreadCount(group) {
  return group.tasks.filter(task => task.status === '未读').length;
}

/**
 * 【新增】计算一个分组中“待办”状态的任务数量
 * @param {object} group - 事务分组对象
 * @returns {number} - “待办”状态的任务总数
 */
function getTodoCount(group) {
  return group.tasks.filter(task => task.status === '待办').length;
}


/**
 * 【修改】创建一个更通用的任务处理函数
 * @param {object} task - 被点击的任务对象
 */
async function handleTaskAction(task) {
  let newStatus = '';

  // 1. 根据当前状态，确定目标新状态
  if (task.status === '未读') {
    newStatus = '待办'; // 核心逻辑：'未读' -> '待办'
  } else if (task.status === '待办') {
    newStatus = '已办'; // '待办' -> '已办'
  } else {
    // 如果任务状态是 '已办' 或其他，理论上按钮不应该显示，为保险起见直接返回
    return;
  }

  try {
    // 2. 调用后端API来更新数据库
    await markTaskAsHandled(task.id, newStatus);

    // 3. API调用成功后，更新前端的本地数据
    task.status = newStatus;

    console.log(`任务 "${task.title}" 已成功更新为 "${newStatus}"`);

  } catch (error) {
    // 4. API调用失败，捕获错误并提示用户
    console.error("更新任务状态失败:", error);
    alert('更新失败，请检查网络或联系管理员！');
  }
}

function getUrgentClass(urgency) {
  return {
    'high': 'task-card--high',
    'medium': 'task-card--medium',
    'low': 'task-card--low'
  }[urgency] || '';
}

function parsePublisherInfo(task) {
  return task.publisherInfo ? task.publisherInfo.replace(' | ', ', ') : `发布者: ${task.publisher}`;
}


// =================================================================
// 4. 日历视图逻辑
// =================================================================
const currentMonth = ref(new Date(today.getFullYear(), today.getMonth(), 1));
const dayNames = ['日', '一', '二', '三', '四', '五', '六'];
const selectedDate = ref(null);
const selectedDateTasks = ref([]);


const allTasksForCalendar = computed(() => {
  return taskGroups.value.flatMap(group => group.tasks);
});




const calendarWeeks = computed(() => {
  const year = currentMonth.value.getFullYear();
  const month = currentMonth.value.getMonth();
  const firstDayOfMonth = new Date(year, month, 1);
  const lastDayOfMonth = new Date(year, month + 1, 0);
  const days = [];
  const startDate = new Date(firstDayOfMonth);
  startDate.setDate(startDate.getDate() - firstDayOfMonth.getDay());
  const endDate = new Date(lastDayOfMonth);
  endDate.setDate(endDate.getDate() + (6 - lastDayOfMonth.getDay()));

  for (let d = new Date(startDate); d <= endDate; d.setDate(d.getDate() + 1)) {
    const currentDate = new Date(d);
    currentDate.setHours(0, 0, 0, 0);

    const tasksEndingToday = allTasksForCalendar.value.filter(task => {
        if (!task.parsedEndDate) return false;
        const taskEnd = new Date(task.parsedEndDate);
        taskEnd.setHours(0, 0, 0, 0);
        return currentDate.getTime() === taskEnd.getTime();
    });

    const tasksOnThisDay = allTasksForCalendar.value.filter(task => {
      if (!task.parsedStartDate || !task.parsedEndDate) return false;
      const taskStart = new Date(task.parsedStartDate);
      taskStart.setHours(0, 0, 0, 0);
      const taskEnd = new Date(task.parsedEndDate);
      taskEnd.setHours(0, 0, 0, 0);
      return currentDate >= taskStart && currentDate <= taskEnd;
    });

    days.push({
      fullDate: currentDate.toISOString().split('T')[0],
      day: currentDate.getDate(),
      month: currentDate.getMonth(),
      year: currentDate.getFullYear(),
      isCurrentMonth: currentDate.getMonth() === month,
      isToday: currentDate.getTime() === today.getTime(),
      tasks: tasksOnThisDay,
      isDeadlineDay: tasksEndingToday.length > 0
    });
  }

  const weeks = [];
  for (let i = 0; i < days.length; i += 7) {
    weeks.push(days.slice(i, i + 7));
  }
  return weeks;
});

const currentMonthDisplay = computed(() => {
  return `${currentMonth.value.getFullYear()}年 ${currentMonth.value.getMonth() + 1}月`;
});

const selectedDateFormatted = computed(() => {
  if (!selectedDate.value) return '';
  return selectedDate.value.toLocaleDateString('zh-CN', { year: 'numeric', month: 'long', day: 'numeric' });
});

function previousMonth() {
  currentMonth.value = new Date(currentMonth.value.getFullYear(), currentMonth.value.getMonth() - 1, 1);
}

function nextMonth() {
  currentMonth.value = new Date(currentMonth.value.getFullYear(), currentMonth.value.getMonth() + 1, 1);
}

function selectDate(day) {
  const clickedDate = new Date(day.year, day.month, day.day);
  clickedDate.setHours(0, 0, 0, 0);
  selectedDate.value = clickedDate;

  selectedDateTasks.value = day.tasks.map(task => {
    if (!task.parsedEndDate) {
      return { ...task, isEndingToday: false };
    }

    const taskEnd = new Date(task.parsedEndDate);
    taskEnd.setHours(0, 0, 0, 0);

    const isEnding = clickedDate.getTime() === taskEnd.getTime();

    return {
      ...task,
      isEndingToday: isEnding
    };
  });
}

function initializeCalendarSelection() {
  const todayCell = calendarWeeks.value.flat().find(d => d.isToday && d.isCurrentMonth);
  if (todayCell) {
    selectDate(todayCell);
  }
}

function getUrgentClassForDot(urgency) {
  return {
    'high': 'dot-high',
    'medium': 'dot-medium',
    'low': 'dot-low'
  }[urgency] || 'dot-default';
}

function getUrgentBadgeClass(urgency) {
  return {
    'high': 'bg-danger',
    'medium': 'bg-warning text-dark',
    'low': 'bg-success'
  }[urgency] || 'bg-secondary';
}

// =================================================================
// 5. 生命周期与侦听器
// =================================================================

onMounted(() => {
  loadTasks();
  if (currentView.value === 'calendar') {
    initializeCalendarSelection();
  }
});

watch(currentView, (newView) => {
  if (newView === 'calendar' && !selectedDate.value) {
    initializeCalendarSelection();
  }
});

watch(currentMonth, () => {
  selectedDate.value = null;
  selectedDateTasks.value = [];
});

// =================================================================
// 6. 详情弹窗逻辑
// =================================================================
const selectedTask = ref(null);
const matterStore = useMatterStore();

async function openTaskDetail(taskId) {
  try {
    const response = await getDetail(taskId);
    selectedTask.value = response.data;
  } catch (error) {
    console.error("获取任务详情失败:", error);
    alert('详情加载失败，请重试！');
  }
}

async function previewFile(messageId) {
  console.log("准备预览文件，Message ID:", messageId); // 1. 确认 messageId 是否正确
  try {
    const fileBlob = await matterStore.fetchFile(messageId);

    console.log("从后端获取到的 Blob 对象:", fileBlob); // 2. 检查返回的 Blob

    // 检查 Blob 是否有效
    if (!fileBlob || !(fileBlob instanceof Blob) || fileBlob.size === 0) {
        console.error("返回的不是有效的 Blob 或 Blob 为空");
        alert("文件不存在或已损坏。");
        return;
    }

    const fileURL = URL.createObjectURL(fileBlob);
    console.log("创建的临时 URL:", fileURL); // 3. 确认 URL 是否成功创建

    window.open(fileURL, '_blank');
  } catch (error) {
    // 4. 打印完整的错误对象，而不仅仅是弹窗
    console.error("在 previewFile 中捕获到完整错误:", error);
    alert("预览文件失败，请检查文件是否存在。");
  }
}

async function previewExcelFile(messageId) {
  console.log("准备预览 Excel 文件，Message ID:", messageId);
  try {
    // 直接调用从 api.js 导入的函数
    const response = await fetchExcelFile(messageId);
    const fileBlob = response.data; // 文件 Blob 在 response.data 中

    console.log("从后端获取到的 Excel Blob 对象:", fileBlob);

    // 检查 Blob 是否有效
    if (!fileBlob || !(fileBlob instanceof Blob) || fileBlob.size === 0) {
        console.error("返回的不是有效的 Blob 或 Blob 为空");
        alert("Excel文件不存在或已损坏。");
        return;
    }

    const fileURL = URL.createObjectURL(fileBlob);
    console.log("为 Excel 文件创建的临时 URL:", fileURL);

    window.open(fileURL, '_blank');
  } catch (error) {
    console.error("在 previewExcelFile 中捕获到完整错误:", error);
    alert("预览 Excel 文件失败，请检查文件是否存在或联系管理员。");
  }
}

function closeModal() {
  selectedTask.value = null;
}

function formatDetailDate(dateString) {
  if (!dateString) return 'N/A';
  const date = new Date(dateString);
  return date.toLocaleString('zh-CN', { hour12: false }).replace(/\//g, '-');
}

const selectedTaskStatusClass = computed(() => {
  if (!selectedTask.value) return '';
  const statusMap = {
    '未读': 'status-unread',
    '待办': 'status-todo',
    '已办': 'status-done',
    '已完成': 'status-done',
  };
  return statusMap[selectedTask.value.status] || 'status-default';
});
</script>

<style>
/* --- 全局和变量定义 --- */
:root {
  --primary-color: #0d6efd;
  --danger-color: #dc3545;
  --warning-color: #ffc107;
  --success-color: #198754;
  --secondary-color: #6c757d;
  --border-color: #e9ecef;
  --card-bg: #ffffff;
  --body-bg: #f8f9fa;
}
body { background-color: var(--body-bg); }

/* ... 其他样式保持不变 ... */
/* --- 视图切换 --- */
.view-switcher span { cursor: pointer; color: var(--secondary-color); transition: color 0.2s; }
.view-switcher span.active { color: var(--primary-color); font-weight: 600; }

/* --- 事务卡片和列表 --- */
.task-list { display: flex; flex-direction: column; gap: 1rem; }
.task-card { background-color: var(--card-bg); border: 1px solid var(--border-color); border-left-width: 4px; border-radius: 8px; padding: 1rem 1.25rem; transition: box-shadow 0.2s, border-color 0.2s; }
.task-card:hover { box-shadow: 0 4px 12px rgba(0,0,0,0.08); }
.task-card--high { border-left-color: var(--danger-color); }
.task-card--medium { border-left-color: var(--warning-color); }
.task-card--low { border-left-color: var(--success-color); }
.task-card-main { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 0.75rem; }
.task-card-title { font-size: 1.1rem; font-weight: 500; color: #212529; }
.task-card-publisher { font-size: 0.85rem; color: var(--secondary-color); white-space: nowrap; margin-left: 1rem; }
.task-card-meta { display: flex; justify-content: space-between; align-items: center; font-size: 0.9rem; color: var(--secondary-color); }
.task-card-dates { font-family: monospace; }

/* --- 轻量化折叠区域 --- */
.task-section-header { display: flex; align-items: center; padding: 10px; border-radius: 8px; cursor: pointer; transition: background-color 0.2s ease; border: 1px solid transparent; }
.task-section-header:hover { background-color: #e9ecef; border-color: #dee2e6; }
.task-section-title { font-size: 1.25rem; font-weight: 600; color: #343a40; }
.chevron-icon { transition: transform 0.3s ease; color: #6c757d; }
.task-section-header.is-collapsed .chevron-icon { transform: rotate(-90deg); }

/* --- Vue Transition 动画 --- */
.slide-fade-enter-active { transition: all 0.3s ease-out; }
.slide-fade-leave-active { transition: all 0.2s cubic-bezier(1, 0.5, 0.8, 1); }
.slide-fade-enter-from, .slide-fade-leave-to { transform: translateY(-10px); opacity: 0; }

/* --- 日历视图样式 --- */
.calendar-grid { border: 1px solid var(--border-color); border-radius: 8px; overflow: hidden; display: grid; grid-template-columns: repeat(7, 1fr); gap: 1px; background-color: var(--border-color); }
.calendar-week, .calendar-header { display: contents; }
.calendar-cell { background-color: var(--card-bg); padding: 8px; min-height: 110px; position: relative; font-size: 0.9em; }
.header-cell { background-color: #f8f9fa; text-align: center; font-weight: 600; min-height: auto; padding: 10px 5px; }
.day-cell { cursor: pointer; transition: background-color 0.2s ease-in-out; }
.day-cell:hover { background-color: #e9ecef; }
.day-number { font-weight: 500; margin-bottom: 5px; text-align: right; }
.other-month { background-color: #f8f9fa; }
.other-month .day-number { color: #adb5bd; }
.today .day-number { background-color: var(--primary-color); color: white; border-radius: 50%; width: 28px; height: 28px; display: inline-flex; align-items: center; justify-content: center; float: right; }
.day-cell.selected { background-color: #dbeafe; box-shadow: inset 0 0 0 2px var(--primary-color); }
.task-indicators { position: absolute; bottom: 8px; left: 8px; display: flex; flex-wrap: wrap; gap: 4px; }
.task-dot { width: 8px; height: 8px; border-radius: 50%; }
.dot-high { background-color: var(--danger-color); }
.dot-medium { background-color: var(--warning-color); }
.dot-low { background-color: var(--success-color); }
.dot-default { background-color: var(--secondary-color); }
.more-tasks-dot { background-color: #6c757d; font-size: 0.7em; width: 14px; height: 14px; text-align: center; line-height: 14px; color: white; }
.selected-day-tasks { background-color: #f8f9fa; border: 1px solid var(--border-color); border-radius: 8px; padding: 1.5rem; }
.day-number-container {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 4px;
  margin-bottom: 5px;
}
.deadline-badge {
  background-color: var(--danger-color);
  color: white;
  font-size: 0.7em;
  font-weight: bold;
  padding: 2px 5px;
  border-radius: 4px;
  line-height: 1;
}

/* ======================================================== */
/* --- 详情弹窗样式 (已从第二个文件同步更新) --- */
/* ======================================================== */
.modal-overlay {
  position: fixed; inset: 0;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex; align-items: center; justify-content: center;
  z-index: 50;
  padding: 1rem;
}
.modal-container {
  background-color: white;
  border-radius: 8px;
  box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1);
  max-width: 600px;
  width: 100%;
  max-height: 90vh;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
}
.modal-content {
  padding: 1.5rem;
}
.modal-title {
  font-size: 1.25rem;
  font-weight: 600;
  color: #111827;
  margin: 0 0 1.5rem 0;
  padding-bottom: 0;
  border-bottom: none;
}
.modal-body {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}
.detail-item {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding-bottom: 0;
  border-bottom: none;
}
.detail-label {
  font-size: 0.875rem;
  font-weight: 600;
  color: #374151;
  text-align: left; /* 改为左对齐 */
}
.detail-value {
  font-size: 0.875rem;
  color: #6b7280;
  margin: 0;
  padding: 0.5rem 0.75rem;
  background-color: #f9fafb;
  border-radius: 4px;
  border: 1px solid #e5e7eb;
  word-wrap: break-word;
}
.modal-footer {
  margin-top: 1.5rem;
  display: flex;
  justify-content: flex-end;
  padding: 0;
  border-top: none;
}
.modal-close-btn {
  padding: 0.5rem 1rem;
  background-color: #6b7280;
  color: white;
  border: none;
  border-radius: 6px;
  font-size: 0.875rem;
  cursor: pointer;
  transition: background-color 0.2s;
}
.modal-close-btn:hover {
  background-color: #4b5563;
}


/* ======================================================== */
/* --- 状态徽章样式 (已从第二个文件同步更新) --- */
/* ======================================================== */
.status-badge {
  padding: 0.25rem 0.75rem;
  border-radius: 12px;
  font-size: 0.75rem;
  font-weight: 500;
  text-align: center;
  display: inline-block;
  white-space: nowrap;
  align-self: flex-start; /* 关键：在 flex 布局中不拉伸 */
}

/* 对应目标文件的 status-badge-unread (红色) */
.status-unread { background-color: #fee2e2; color: #991b1b; }

/* 对应目标文件的 status-badge-pending (黄色) */
.status-todo { background-color: #fef9c3; color: #854d0e; }

/* 对应目标文件的 status-badge-done (绿色) */
.status-done { background-color: #dcfdf7; color: #065f46; }

.status-default { background-color: #e5e7eb; color: #374151; }
</style>
